package com.galaxy.payment.service.impl;

import com.galaxy.common.core.domain.R;
import com.galaxy.payment.api.RemoteOrderService;
import com.galaxy.payment.api.RemoteUserService;
import com.galaxy.payment.domain.OrderBo;
import com.galaxy.payment.domain.PaymentRecord;
import com.galaxy.payment.domain.bo.AccountFlowBo;
import com.galaxy.payment.domain.bo.PaymentBo;
import com.galaxy.payment.domain.vo.PaymentRecordVo;
import com.galaxy.payment.service.IAccountFlowService;
import com.galaxy.payment.service.IAliPayService;
import com.galaxy.payment.service.IBalanceService;
import com.galaxy.payment.service.IPaymentRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Date;

@Slf4j
@Service
@RequiredArgsConstructor
public class BalanceServiceImpl  implements IBalanceService {

    @Autowired
    private IPaymentRecordService paymentRecordService;

    @Autowired
    private RemoteOrderService remoteOrderService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private IAccountFlowService accountFlowService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createPayByBalance(PaymentBo paymentRecord) {
        PaymentRecordVo paymentRecord1 = paymentRecordService.getPaymentRecordByOrderNo(paymentRecord.getOrderNo());
        // 1. 创建支付记录
        if(paymentRecord1 == null){
            log.info("使用余额支付");
            paymentRecord.setPaymentType(2);
            paymentRecord.setPayTime(new Date());
            paymentRecord.setStatus(2);
            Date now = new Date();
            Instant instant = now.toInstant();
            Instant expireInstant = instant.plus(Duration.ofMinutes(15));
            Date expireTime = Date.from(expireInstant);
            paymentRecord.setExpireTime(expireTime);
            paymentRecord.setSuccessTime(new Date());
            paymentRecordService.insertByBo(paymentRecord);
            OrderBo orderBo =  new OrderBo();
            orderBo.setId(paymentRecord.getOrderId());
            orderBo.setPayType(2);
            orderBo.setStatus(2);
            orderBo.setOutTradeNo(paymentRecord.getPayNo());
            orderBo.setCompleteTime(LocalDateTime.now());
            orderBo.setPayTime(LocalDateTime.now());
            R<Boolean> edit = remoteOrderService.edit(orderBo);
            if(edit.getData()){
                Boolean data = remoteUserService.updateBalance(paymentRecord.getUserId(), paymentRecord.getPaymentAmount()).getData();
                if(data){
                    AccountFlowBo accountFlowBo = new AccountFlowBo();
                    accountFlowBo.setUserId(paymentRecord.getUserId());
                    accountFlowBo.setOrderNo(paymentRecord.getOrderNo());
                    accountFlowBo.setFlowType(2);
                    accountFlowBo.setAmount(paymentRecord.getPaymentAmount().negate());

                    accountFlowBo.setBalance(BigDecimal.ZERO);
                    accountFlowBo.setDescription("余额购买商品");
                    accountFlowService.insertByBo(accountFlowBo);
                }
                return data;
            }
        }else{
            if(paymentRecord1.getStatus() == 1 || paymentRecord1.getStatus() == 0){
                OrderBo orderBo =  new OrderBo();
                orderBo.setId(paymentRecord.getOrderId());
                orderBo.setPayType(2);
                orderBo.setStatus(2);
                R<Boolean> edit = remoteOrderService.edit(orderBo);
                if(edit.getData()){
                    return remoteUserService.updateBalance(paymentRecord.getUserId(), paymentRecord.getPaymentAmount()).getData();
                }
            }else if(paymentRecord1.getStatus() == 2){
                return true;
            }
        }
        return false;
    }
}
